﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SWEN3Application.Classes;
using System.Collections;
using System.Text.RegularExpressions;

namespace SWEN3Application
{
    public partial class ManageBooking : MasterForm
    {
        LinkedList<BookingList> ll;
        BookingList b;
        public ManageBooking()
        {
            InitializeComponent();
            Load_Booking();
            int i = 0;
            do
            {
                ManageBookingCheckedListBox.SetItemChecked(i, true);
                i++;
            }
            while (i < ManageBookingCheckedListBox.Items.Count);
            BookingTabControl.SelectedIndex = 0;
        }

        private void Load_Booking()
        {
            ManageBookingDataGridView.Rows.Clear();

            ManageBookingDataGridView.ColumnCount = 10;
            ManageBookingDataGridView.Columns[0].Name = "Booking No";
            ManageBookingDataGridView.Columns[1].Name = "Last Name";
            ManageBookingDataGridView.Columns[2].Name = "First Name";
            ManageBookingDataGridView.Columns[3].Name = "Number of Adults";
            ManageBookingDataGridView.Columns[4].Name = "Number of Childrens";
            ManageBookingDataGridView.Columns[5].Name = "Phone No";
            ManageBookingDataGridView.Columns[6].Name = "Email Address";
            ManageBookingDataGridView.Columns[7].Name = "Address";
            ManageBookingDataGridView.Columns[8].Name = "Country";
            ManageBookingDataGridView.Columns[9].Name = "Remarks";

            ll = BookingDBManager.GetAllBooking();
            for (LinkedListNode<BookingList> i = ll.First; i != null; i = i.Next)
            {
                BookingList b = i.Value;
                Object[] row = { b.BookingNo, b.LastName, b.FirstName, b.AdultsNo, b.ChildsNo, b.PhoneNo, b.EmailAddress, b.Address, b.Country, b.Remarks };
                ManageBookingDataGridView.Rows.Add(row);
            }
            ManageBookingDataGridView.Refresh();
        }

        private void BookingTabControl_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (BookingTabControl.SelectedIndex == 0)
            {
                Load_Booking();
                if (ManageBookingDataGridView.DisplayedRowCount(false) == 0)
                {
                    MessageBox.Show("No booking have been created yet.");
                }
            }
        }

        private void ManageBookingCheckedListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            int i = ManageBookingCheckedListBox.SelectedIndex;
            if (ManageBookingCheckedListBox.GetItemChecked(i))
            {
                ManageBookingDataGridView.Columns[i + 3].Visible = true;
            }
            else
            {
                ManageBookingDataGridView.Columns[i + 3].Visible = false;
            }
            ManageBookingCheckedListBox.Refresh();
            ManageBookingDataGridView.Refresh();
        }

        private void FindBookingNo_TextChanged(object sender, EventArgs e)
        {
            if (Regex.IsMatch(FindBookingNo.Text, @"^\d+$"))
            {
                ManageBookingDataGridView.ClearSelection();
                for (int i = 0; i < ManageBookingDataGridView.RowCount; i++)
                {
                    int bookingNo = Convert.ToInt32(ManageBookingDataGridView.Rows[i].Cells[0].Value);
                    if (bookingNo == Convert.ToInt32(FindBookingNo.Text))
                    {
                        ManageBookingDataGridView.Rows[i].Selected = true;
                        ManageBookingDataGridView.FirstDisplayedScrollingRowIndex = i;
                        break;
                    }
                }
            }
        }

        private void AdultsNumeric_ValueChanged(object sender, EventArgs e)
        {
            if (AdultsNumeric.Value == 0)
            {
                ChildsNumeric.Enabled = false;
                ChildsNumeric.Value = 0;
            }
            else
            {
                ChildsNumeric.Enabled = true;
            }
        }

        private void ManageBookingDataGridView_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex != -1)
            {
                BookingTabControl.SelectedIndex = 1;
                BookingNo.Text = ManageBookingDataGridView[0, e.RowIndex].Value.ToString();
            }
        }

        private void BookingNo_TextChanged(object sender, EventArgs e)
        {
            if (Regex.IsMatch(BookingNo.Text, @"^\d+$"))
            {
                b = BookingDBManager.GetBookingByBookingNo(Convert.ToInt32(BookingNo.Text));
                if (b != null)
                {
                    errorProvider.Clear();
                    BookingInformationBox.Visible = true;
                    setData();
                }
                else
                {
                    errorProvider.SetError(BookingNo, "Booking Number not found!");
                    BookingInformationBox.Visible = false;
                }
            }
            else
            {
                errorProvider.SetError(BookingNo, "Invalid Booking Number format!");
                BookingInformationBox.Visible = false;
            }
        }

        private void setData()
        {
            LastName.Text = b.LastName;
            FirstName.Text = b.FirstName;
            AdultsNumeric.Value = b.AdultsNo;
            ChildsNumeric.Value = b.ChildsNo;
            PhoneNo.Text = b.PhoneNo;
            EmailAddress.Text = b.EmailAddress;
            HomeAddress.Text = b.Address;
            Remarks.Text = b.Remarks;
            Country.Text = b.Country;
        }

        private void Reset_Click(object sender, EventArgs e)
        {
            setData();
        }

        private Boolean CustomValidate()
        {
            Boolean IsValid = true;
            errorProvider.Clear();
            if (String.IsNullOrEmpty(BookingNo.Text))
            {
                IsValid = false;
                errorProvider.SetError(BookingNo, "Booking No field is empty.");
            }
            else
            {
                foreach (Control ctrl in BookingInformationBox.Controls)
                {
                    TextBox tb = ctrl as TextBox;
                    if (tb != null)
                    {
                        if (String.IsNullOrEmpty(tb.Text))
                        {
                            if (tb.Name != "Remarks")
                            {
                                IsValid = false;
                                errorProvider.SetError(tb, "The field is empty!");
                            }
                        }
                        else if (tb.Name == "EmailAddress")
                        {

                            if (!Regex.IsMatch(tb.Text, @"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"))
                            {
                                IsValid = false;
                                errorProvider.SetError(tb, "Invalid email address format!");
                            }
                        }
                    }
                }
            }
            return IsValid;
        }

        private void Save_Click(object sender, EventArgs e)
        {
            try
            {
                if (CustomValidate())
                {
                    BookingList newBooking = new BookingList();
                    newBooking.BookingNo = Convert.ToInt32(BookingNo.Text);
                    newBooking.LastName = LastName.Text;
                    newBooking.FirstName = FirstName.Text;
                    newBooking.AdultsNo = (int)AdultsNumeric.Value;
                    newBooking.ChildsNo = (int)ChildsNumeric.Value;
                    newBooking.PhoneNo = PhoneNo.Text;
                    newBooking.EmailAddress = EmailAddress.Text;
                    newBooking.Address = HomeAddress.Text;
                    newBooking.Remarks = Remarks.Text;
                    newBooking.Country = Country.Text;

                    if (BookingDBManager.UpdateBookingDetails(newBooking))
                    {
                        b = newBooking;
                        MessageBox.Show("Update Successful!");
                    }
                    else
                    {
                        MessageBox.Show("Update Booking Fail!");
                    }
                }
            }
            //This is to catch all types of exception that is not handled by the if else. 
            //Also to ensure the application is still running.
            catch (Exception ex)
            {
                MessageBox.Show("A serious error has occured during updating booking process.");
            }
        }

        private void DeleteBookingNo_TextChanged(object sender, EventArgs e)
        {
            try
            {
                if (!String.IsNullOrEmpty(DeleteBookingNo.Text) && Regex.IsMatch(DeleteBookingNo.Text, @"^\d+$"))
                {
                    int BookingNo = Convert.ToInt32(DeleteBookingNo.Text);
                    BookingList b = BookingDBManager.GetBookingByBookingNo(BookingNo);
                    if (b != null)
                    {
                        Rooms r = RoomDBManager.GetRoomByBookingNo(BookingNo);
                        if (r == null)
                        {
                            Invoice i = InvoiceDBManager.GetInvoiceByBookingNo(BookingNo);
                            if (i == null)
                            {
                                Delete.Visible = true;
                                ErrMsg.ForeColor = Color.Green;
                                ErrMsg.Text = "This booking number can be deleted.";
                            }
                            else
                            {
                                Delete.Visible = false;
                                ErrMsg.ForeColor = Color.Red;
                                ErrMsg.Text = "This booking number cannot be deleted. Invoice Id : " + i.InvoiceId + " has this booking number. ";
                            }
                        }
                        else
                        {
                            Delete.Visible = false;
                            ErrMsg.ForeColor = Color.Red;
                            ErrMsg.Text = "This booking number cannot be deleted. Room number : " + r.RoomNo + " has this booking number. ";
                        }
                    }
                    else
                    {
                        Delete.Visible = false;
                        ErrMsg.ForeColor = Color.Red;
                        ErrMsg.Text = "Booking number not found.";
                    }
                }
                else
                {
                    Delete.Visible = false;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("A serious error occured while checking the booking number.");
            }
        }

        private void Delete_Click(object sender, EventArgs e)
        {
            try
            {
                if (!String.IsNullOrEmpty(DeleteBookingNo.Text) && Regex.IsMatch(DeleteBookingNo.Text, @"^\d+$"))
                {
                    int BookingNo = Convert.ToInt32(DeleteBookingNo.Text);
                    if (BookingDBManager.DeleteBookingByBookingNo(BookingNo) > 0)
                    {
                        DeleteBookingNo.Text = "";
                        ErrMsg.ForeColor = Color.Green;
                        ErrMsg.Text = "Booking has been successfully deleted.";
                    }
                    else
                    {
                        ErrMsg.ForeColor = Color.Red;
                        ErrMsg.Text = "Fail to Delete";
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("A serious error occured during deleting booking process.");
            }
            finally
            {
                Delete.Visible = false;
            }
        }
    }
}
